package org.third.security.jaas;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import java.io.IOException;
import java.security.Principal;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class HelloLoginModule2 implements LoginModule {
    private boolean isAuthenticated = false;
    private CallbackHandler callbackHandler;
    private javax.security.auth.Subject subject;
    private Set<Principal> principals;

    public HelloLoginModule2() {
    }

    @Override
    public void initialize(javax.security.auth.Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        this.principals = new HashSet<Principal>();
        this.subject = subject;
        this.callbackHandler = callbackHandler;
    }

    @Override
    public boolean login() throws LoginException {
        try {
            NameCallback nameCallback = new NameCallback("Type in userName-XXXXX: ");
            PasswordCallback passwordCallback = new PasswordCallback("Type in Password", false);
            final Callback[] calls = new Callback[] { nameCallback, passwordCallback };
            System.out.println("=======>>" + this.getClass().getName());
            // 获取用户数据
            callbackHandler.handle(calls);
            String username = nameCallback.getName();
            String password = String.valueOf(passwordCallback.getPassword());

            // TODO 验证，如：查询数据库、LDAP。。。

            if (username.endsWith("-002")) {// 验证通过
                principals.add(new UniqueNamePrincipal(username + "->X002"));
                principals.add(new EmailPrincipal(username + "->X002"));
                isAuthenticated = true;
            } else {
                throw new LoginException("user or password is wrong");
            }

        } catch (IOException e) {
            throw new LoginException("no such user");
        } catch (UnsupportedCallbackException e) {
            throw new LoginException("login failure");
        }
        return isAuthenticated;
    }

    /**
     * 验证后的处理,在Subject中加入用户对象
     */
    @Override
    public boolean commit() throws LoginException {
        if (isAuthenticated) {
            subject.getPrincipals().addAll(principals);
        } else {
            throw new LoginException("Authentication failure");
        }
        return isAuthenticated;
    }

    @Override
    public boolean abort() throws LoginException {
        return false;
    }

    @Override
    public boolean logout() throws LoginException {
        subject.getPrincipals().removeAll(principals);
        principals = null;
        return true;
    }
}